home *** CD-ROM | disk | FTP | other *** search
- /*
- * XaAES - XaAES Ain't the AES
- *
- * A multitasking AES replacement for MiNT
- *
- */
-
- #include <VDI.H>
- #include <MINTBIND.H>
- #include <memory.h>
- #include "XA_TYPES.H"
- #include "XA_DEFS.H"
- #include "XA_GLOBL.H"
- #include "STD_WIDG.H"
- #include "BOX3D.H"
- #include "C_WINDOW.H"
- #include "RECTLIST.H"
- #include "MESSAGES.H"
- #include "OBJECTS.H"
- #include "RESOURCE.H"
- #include "SYSTEM.H"
- #include "DESKTOP.H"
- #include "graf_mou.h"
-
- /*
- Low-level Window Stack Management Functions
- */
-
- XA_WINDOW *window_list=NULL; /* The global system window stack */
- short wind_handle=0; /* Window handle counter (used to generate unique window handles)
- As this loops round, there may be a problem if a user opens
- more than 32767 windows in one session :) */
-
- /*
- Create a window
- */
- XA_WINDOW *create_window(short pid, long tp, short rx, short ry, short rw, short rh)
- {
- XA_WINDOW *nw=(XA_WINDOW *)malloc(sizeof(XA_WINDOW));
-
- DIAGS(("create_window()\n"));
-
- if (!nw) /* Unable to allocate memory for window? */
- return NULL;
-
- nw->x=rx;
- nw->y=ry;
- nw->w=rw;
- nw->h=rh;
- nw->prev_x=rx;
- nw->prev_y=ry;
- nw->prev_w=rw;
- nw->prev_h=rh;
- nw->handle=wind_handle++;
- nw->owner=pid;
- nw->is_open=FALSE;
- nw->rect_user=nw->rect_list=nw->rect_start=NULL;
- nw->redraw=NULL;
- nw->destructor=NULL;
- nw->keypress=NULL;
- nw->window_status=XAWS_CLOSED;
-
- DIAGS((" allocated:handle=%d\n",nw->handle));
-
- Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
-
- if (root_window) /* Append window to back of window list, behind the root window (if it exists) */
- {
- DIAGS((" inserted behind root window\n"));
- nw->prev=root_window;
- nw->next=root_window->next;
- if (root_window->next)
- root_window->next->prev=nw;
- root_window->next=nw;
- }else{
- DIAGS((" no root, initial window created\n"));
- nw->next=NULL;
- nw->prev=NULL;
- window_list=nw;
- }
-
- Psemaphore(3,WIN_LIST_SEMAPHORE,0);
-
- standard_widgets(nw,tp); /* Attatch the appropriate widgets to the window */
-
- if (tp&STORE_BACK) /* If STORE_BACK extended attribute is used, window preserves it's own background */
- {
- DIAGS((" allocating background storage buffer\n"));
- nw->background=(void*)malloc(display.planes*((rw+35)>>2)*(rh+20));
- nw->bgx=-1;
- }else{
- nw->background=NULL;
- }
-
- calc_work_area(nw); /* Calculate an initial work area */
-
- return nw;
- }
-
- /*
- Display a window
- */
- void display_window(XA_WINDOW *wind)
- {
- short f,pnt[8],x,y,w,h;
- WidgetCallback wc;
-
- DIAGS(("display_window(handle=%d)\n",wind->handle));
-
- if ((window_list==wind)&&(wind->active_widgets&STORE_BACK)) /* Is this a 'preserve own background' window? */
- {
- MFDB Mscreen;
- MFDB Mpreserve;
-
- pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=wind->x+wind->w; pnt[3]=wind->y+wind->h;
- pnt[4]=0; pnt[5]=0; pnt[6]=wind->w; pnt[7]=wind->h;
-
- Mpreserve.fd_w=wind->w+20;
- Mpreserve.fd_h=wind->h+20;
- Mpreserve.fd_wdwidth=(Mpreserve.fd_w+15)>>4;
- Mpreserve.fd_nplanes=display.planes;
- Mpreserve.fd_stand=0;
- Mpreserve.fd_addr=wind->background;
-
- Mscreen.fd_addr=NULL;
-
- v_hide_c(V_handle);
- vro_cpyfm(V_handle, S_ONLY, pnt, &Mscreen, &Mpreserve);
- v_show_c(V_handle,1);
-
- wind->bgx=wind->x; wind->bgy=wind->y;
- }else{
- wind->bgx=-1;
- }
-
- x=wind->wx;
- y=wind->wy;
- w=wind->ww;
- h=wind->wh;
-
- /* Display the window backdrop (borders only, GEM style) */
- vsf_color(V_handle,display.dial_colours.bg_col);
- vsf_interior(V_handle,FIS_SOLID);
- if (wind->active_widgets&NO_WORK)
- {
- pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=wind->x+wind->w-SHADOW_OFFSET; pnt[3]=wind->y+wind->h-SHADOW_OFFSET;
- v_bar(V_handle,pnt);
- }else{
- pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=wind->x+wind->w-SHADOW_OFFSET; pnt[3]=y;
- v_bar(V_handle,pnt);
- pnt[1]=y+h; pnt[3]=wind->y+wind->h-SHADOW_OFFSET;
- v_bar(V_handle,pnt);
- pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=x;
- v_bar(V_handle,pnt);
- pnt[0]=x+w; pnt[2]=wind->x+wind->w-SHADOW_OFFSET;
- v_bar(V_handle,pnt);
- }
-
- /* Display drop shadow */
- vsf_color(V_handle,display.dial_colours.border_col);
- pnt[0]=wind->x+wind->w-SHADOW_OFFSET+1; pnt[1]=wind->y+SHADOW_OFFSET; pnt[2]=wind->x+wind->w-1; pnt[3]=wind->y+wind->h-1;
- v_bar(V_handle,pnt);
- pnt[0]=wind->x+SHADOW_OFFSET-1; pnt[1]=wind->y+wind->h-SHADOW_OFFSET+1; pnt[2]=wind->x+wind->w-SHADOW_OFFSET; pnt[3]=wind->y+wind->h-1;
- v_bar(V_handle,pnt);
-
- /* Display the work area */
- if (!(wind->active_widgets&NO_WORK))
- {
- vsl_color(V_handle,display.dial_colours.b_r_col);
-
- pnt[0]=x; pnt[1]=y+h;
- pnt[2]=x; pnt[3]=y;
- pnt[4]=x+w; pnt[5]=y;
- v_pline(V_handle,3,pnt);
-
- pnt[0]=x+2; pnt[1]=y+h-1;
- pnt[2]=x+w-1; pnt[3]=y+h-1;
- pnt[4]=x+w-1; pnt[5]=y+1;
- v_pline(V_handle,3,pnt);
-
- vsl_color(V_handle,display.dial_colours.t_l_col);
-
- pnt[0]=x+w; pnt[1]=y+1;
- pnt[2]=x+w; pnt[3]=y+h;
- pnt[4]=x+1; pnt[5]=y+h;
- v_pline(V_handle,3,pnt);
-
- pnt[0]=x+1; pnt[1]=y+h-1;
- pnt[2]=x+1; pnt[3]=y+1;
- pnt[4]=x+w-1; pnt[5]=y+1;
- v_pline(V_handle,3,pnt);
- }
-
- /* Go through and display the window widgets using their display behaviour */
- if (wind->window_status==XAWS_ICONIFIED)
- {
- wc=wind->widgets[XAW_TITLE].behaviour[XACB_DISPLAY];
- (*wc)(wind, &(wind->widgets[XAW_TITLE]));
- wc=wind->widgets[XAW_ICONIFY].behaviour[XACB_DISPLAY];
- (*wc)(wind, &(wind->widgets[XAW_ICONIFY]));
- }else{
- for(f=0; f<XA_MAX_WIDGETS; f++)
- {
- wc=wind->widgets[f].behaviour[XACB_DISPLAY];
- if (wc)
- (*wc)(wind, &(wind->widgets[f]));
- }
- }
-
- /* If the window has an auto-redraw function, call it */
- if (wind->redraw)
- {
- (*(wind->redraw))(wind);
- }
-
- }
-
- XA_WINDOW *wind_find(short x, short y)
- {
- XA_WINDOW *w=window_list;
-
- Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
-
- while(w)
- {
- if ((w->is_open)&&((((x>=w->x)&&(y>=w->y))&&(x<w->x+w->w))&&(y<w->y+w->h)))
- {
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
- return w;
- }
- w=w->next;
- }
-
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
-
- return NULL;
- }
-
-
- XA_WINDOW *get_wind_by_handle(short h)
- {
- XA_WINDOW *w;
-
- Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
-
- w=window_list;
-
- while(w)
- {
- if (w->handle==h)
- {
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
- return w;
- }
- w=w->next;
- }
-
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
-
- return NULL;
- }
-
- /*
- Pull this window to the head of the window list
- */
- void pull_wind_to_top(XA_WINDOW *w)
- {
- XA_CLIENT *owner;
- XA_WINDOW *wl=w->prev;
- GRECT clip,r;
- DIAGS(("pull_wind_to_top(%d)\n",w->handle));
-
- Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
-
- if (window_list->owner!=w->owner) /* If we're getting a new top window, we may need */
- { /* to swap menu bars..... */
- XA_WIDGET_TREE *menu_bar;
-
- Psemaphore(2,ROOT_SEMAPHORE,-1L);
-
- menu_bar=(XA_WIDGET_TREE*)(root_window->widgets[XAW_MENU].stuff);
-
- owner=Pid2Client(w->owner);
- menu_bar->tree=owner->std_menu;
- menu_bar->owner=w->owner;
-
- if ((owner->desktop) /* Change desktops? */
- &&((owner->desktop!=desktop)&&(owner->desktop!=ResourceTree(system_resources,DEF_DESKTOP))))
- {
- set_desktop(owner->desktop);
- root_window->owner=w->owner;;
-
- v_hide_c(V_handle);
- display_non_topped_window(root_window,NULL);
- v_show_c(V_handle,1);
- }else{ /* No - just change menu bars */
- rp_2_ap(root_window, root_window->widgets+XAW_MENU, &clip.g_x, &clip.g_y);
-
- clip.g_w=root_window->widgets[XAW_MENU].w;
- clip.g_h=root_window->widgets[XAW_MENU].h;
-
- v_hide_c(V_handle);
- display_non_topped_window(root_window,&clip);
- v_show_c(V_handle,1);
- }
-
- Psemaphore(3,ROOT_SEMAPHORE,0L);
- }
-
- wl=w->prev;
-
- r.g_x=w->x; r.g_y=w->y;
- r.g_w=w->w; r.g_h=w->h;
-
- if (w->prev)
- {
- w->prev->next=w->next;
- }else{
- window_list=w->next;
- }
- if (w->next)
- w->next->prev=w->prev;
- w->next=window_list;
- if (window_list) window_list->prev=w;
- w->prev=NULL;
- window_list=w;
-
- while(wl)
- {
- DIAGS(("candidate window=%d\n",wl->handle));
- clip.g_x=wl->x; clip.g_y=wl->y;
- clip.g_w=wl->w; clip.g_h=wl->h;
- if (rc_intersect(&r,&clip))
- {
- DIAGS((" - regenerate rect_list for %d\n",wl->handle));
- generate_rect_list(wl);
- }
- wl=wl->prev;
- }
-
- generate_rect_list(w);
-
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
-
- }
-
- void send_wind_to_bottom(XA_WINDOW *w)
- {
- XA_WINDOW *old_top=window_list,*wl=w->next;
- GRECT r,clip;
-
- if (w->next==root_window) return; /* Can't send to the bottom a window that's already there */
-
- Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
-
- if (w==window_list) /* If this window was on top, change window list */
- window_list=w->next;
-
- if (w->next) /* Remove window from window list */
- w->next->prev=w->prev;
-
- if (w->prev)
- w->prev->next=w->next;
-
- w->prev=root_window->prev;
- w->next=root_window;
-
- if (w->prev) /* root window is always at the bottom */
- {
- w->prev->next=w;
- }else{
- window_list=w; /* window is still on top (must be the only window */
- }
-
- root_window->prev=w;
-
- if (window_list==old_top) /* If no change in top window, we can return here */
- {
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
- return;
- }
-
- r.g_x=w->x; r.g_y=w->y;
- r.g_w=w->w; r.g_h=w->h;
-
- while(wl!=root_window->next)
- {
- clip.g_x=wl->x; clip.g_y=wl->y;
- clip.g_w=wl->w; clip.g_h=wl->h;
- if (rc_intersect(&r,&clip))
- generate_rect_list(wl);
- wl=wl->next;
- }
-
- generate_rect_list(w);
-
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
-
- if (old_top->owner!=window_list->owner) /* If we're getting a new top window, we may need */
- { /* to swap menu bars..... */
- XA_WIDGET_TREE *menu_bar=(XA_WIDGET_TREE*)(root_window->widgets[XAW_MENU].stuff);
- XA_CLIENT *owner;
-
- Psemaphore(2,ROOT_SEMAPHORE,-1L);
-
- owner=Pid2Client(window_list->owner);
- menu_bar->tree=owner->std_menu;
- menu_bar->owner=window_list->owner;
-
- if (owner->desktop /* Change desktops? */
- &&((owner->desktop!=desktop)&&(owner->desktop!=ResourceTree(system_resources,DEF_DESKTOP))))
- {
- set_desktop(owner->desktop);
- root_window->owner=window_list->owner;
-
- v_hide_c(V_handle);
- display_non_topped_window(root_window,NULL);
- v_show_c(V_handle,1);
- }else{ /* No - just change menu bars */
- rp_2_ap(root_window, root_window->widgets+XAW_MENU, &clip.g_x, &clip.g_y);
-
- clip.g_w=root_window->widgets[XAW_MENU].w;
- clip.g_h=root_window->widgets[XAW_MENU].h;
-
- v_hide_c(V_handle);
- display_non_topped_window(root_window,&clip);
- v_show_c(V_handle,1);
- }
-
- Psemaphore(3,ROOT_SEMAPHORE,0L);
- }
- }
-
- /*
- Change an open window's coordinates, updating rectangle lists as appropriate
- */
- void move_window(XA_WINDOW *wind,short x,short y,short w,short h)
- {
- XA_WINDOW *wl;
- XA_RECT_LIST *rl=rect_get_system_first(wind);
- GRECT r_wind_old,r_wind_new,clip;
- short blit_mode,coords[8];
- MFDB Mscreen;
-
- Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
-
- wind->prev_x=wind->x; /* Save windows previous coords */
- wind->prev_y=wind->y;
- wind->prev_w=wind->w;
- wind->prev_h=wind->h;
-
- r_wind_old.g_x=wind->x; r_wind_old.g_y=wind->y;
- r_wind_old.g_w=wind->w; r_wind_old.g_h=wind->h;
-
- wind->x=x; /* Change the window coords */
- wind->y=y;
- wind->w=w;
- wind->h=h;
-
- blit_mode=((wind==window_list)
- &&((wind->prev_x+wind->prev_w<display.w)&&(wind->prev_y+wind->prev_h<display.h))
- &&((x+w<display.w)&&(y+h<display.h))
- &&((wind->prev_w==w)&&(wind->prev_h==h)));
-
- calc_work_area(wind); /* Recalculate the work area (as well as moving, */
- /* it might have changed size). */
-
- generate_rect_list(wind); /* update the window's rectangle list, it will be out of date now */
-
- v_hide_c(V_handle);
-
- clear_clip();
-
- if (blit_mode) /* If window is being blit mode transferred, do the blit instead of redrawing */
- {
- Mscreen.fd_addr=NULL;
- coords[0]=wind->prev_x; coords[1]=wind->prev_y;
- coords[2]=wind->prev_x+wind->prev_w-1; coords[3]=wind->prev_y+wind->prev_h-1;
- coords[4]=x; coords[5]=y;
- coords[6]=x+w-1; coords[7]=y+w-1;
-
- vro_cpyfm(V_handle, S_ONLY, coords, &Mscreen, &Mscreen);
- }else{
- display_non_topped_window(wind,NULL);
- if (!(wind->active_widgets&NO_MESSAGES)) /* does this window's application want messages? if so send it a redraw */
- send_app_message(wind->owner, WM_REDRAW, 0, wind->handle, wind->wx, wind->wy, wind->ww, wind->wh);
- }
-
- for(wl=wind->next; wl!=root_window->next; wl=wl->next)
- {
- clip.g_x=wl->x; clip.g_y=wl->y;
- clip.g_w=wl->w; clip.g_h=wl->h;
-
- if (rc_intersect(&r_wind_old,&clip)) /* Check for newly exposed windows */
- {
-
- generate_rect_list(wl);
- display_non_topped_window(wl,&clip);
- if (!(wl->active_widgets&NO_MESSAGES)) /* does this window's application want messages? if so send it a redraw */
- send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
-
- }else{
-
- clip.g_x=wl->x; clip.g_y=wl->y;
- clip.g_w=wl->w; clip.g_h=wl->h;
- if (rc_intersect(&r_wind_new,&clip)) /* Check for newly covered windows */
- generate_rect_list(wl); /* We don't need to send a redraw to these windows, we just have to update their rect lists */
-
- }
- }
-
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
-
- v_show_c(V_handle,1);
- }
-
-
- /*
- Close an open window and re-display any windows underneath
- it. Also places window behind root window but does NOT delete it - the window
- will still exist after this call.
- */
- short close_window(XA_WINDOW *wind)
- {
- XA_WINDOW *wl;
- GRECT r,clip;
- XA_CLIENT *client;
- short is_top;
-
- if (wind==NULL)
- {
- DIAGS(("WARNING:close_window:Invalid window pointer\n"));
- return 0; /* Invalid window handle, return error */
- }
-
- if (wind->is_open==FALSE)
- return 0;
-
- is_top=(wind==window_list);
-
- wl=wind->next;
-
- r.g_x=wind->x; r.g_y=wind->y;
- r.g_w=wind->w; r.g_h=wind->h;
-
- wind->is_open=FALSE; /* tag window as closed */
- wind->window_status=XAWS_CLOSED;
-
- Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
-
- if (wind->prev) /* Remove the window from the window list */
- wind->prev->next=wind->next;
-
- if (wind->next)
- wind->next->prev=wind->prev;
-
- wind->next=root_window->next; /* Keep closed windows on the other side of the root window */
- wind->prev=root_window;
- if (root_window->next)
- root_window->next->prev=wind;
- root_window->next=wind;
-
- if (is_top)
- window_list=wl;
-
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
-
- v_hide_c(V_handle);
- /* Redisplay any windows below the one we are closing */
- while(wl!=wind)
- {
- clip.g_x=wl->x; clip.g_y=wl->y;
- clip.g_w=wl->w; clip.g_h=wl->h;
- if (rc_intersect(&r,&clip))
- {
- generate_rect_list(wl);
- display_non_topped_window(wl, &clip);
- if (!(wl->active_widgets&NO_MESSAGES)) /* does this window's application want messages? if so send it a redraw */
- send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
- }
- wl=wl->next;
- }
-
- if ((is_top)&&(window_list!=root_window)) /* New top window should be displayed in it's entirety */
- {
- display_non_topped_window(window_list, NULL);
- if(!(window_list->active_widgets&NO_MESSAGES))
- {
- send_app_message(window_list->owner, WM_ONTOP, 0, window_list->handle, 0, 0, 0, 0);
- send_app_message(window_list->owner, WM_REDRAW, 0, window_list->handle, r.g_x, r.g_y, r.g_w, r.g_h);
- }
- }
-
- v_show_c(V_handle,1);
-
- client=Pid2Client(window_list->owner);
- /* New top window - change the cursor to this clients choice */
- graf_mouse(client->client_mouse, client->client_mouse_form);
-
- return 1;
- }
-
- void delete_window(XA_WINDOW *wind)
- {
- if (!wind) return;
-
- Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
-
- if (wind->destructor)
- (*(wind->destructor))(wind); /* Call the window destructor if any */
-
- if (wind==window_list)
- window_list=wind->next;
-
- if (wind->prev) wind->prev->next=wind->next;
- if (wind->next) wind->next->prev=wind->prev;
-
- if (wind->background)
- free(wind->background);
-
- if (wind->rect_start)
- free(wind->rect_start);
-
- Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
-
- free(wind);
- }
-
- /*
- Display a window that isn't on top, respecting clipping
- - pass clip==NULL to redraw whole window, otherwise clip is a pointer to a GRECT that
- defines the clip rectangle.
- */
- void display_non_topped_window(XA_WINDOW *w,GRECT *clip)
- {
- GRECT target;
- XA_RECT_LIST *rl=rect_get_system_first(w);
-
- if (w==window_list)
- {
- set_clip(display.x, display.y, display.w, display.h);
- display_window(w);
- return;
- }
-
- if (w->is_open)
- {
- while(rl)
- {
- if (clip)
- {
- target.g_x=rl->x;
- target.g_y=rl->y;
- target.g_w=rl->w;
- target.g_h=rl->h;
-
- if (rc_intersect(clip,&target))
- {
- set_clip(target.g_x, target.g_y, target.g_w, target.g_h);
- display_window(w);
- }
- }else{
- set_clip(rl->x, rl->y, rl->w, rl->h);
- display_window(w);
- }
- rl=rect_get_system_next(w);
- }
- }
- clear_clip();
- }
-
- /*
- Display windows below a given rectangle, starting with window w.
- */
- void display_windows_below(GRECT *r, XA_WINDOW *w)
- {
- GRECT win_r;
- XA_WINDOW *wl;
- XA_RECT_LIST *rl;
-
- for(wl=w; wl!=root_window->next; wl=wl->next)
- {
-
- if (wl->is_open)
- {
- for(rl=rect_get_system_first(wl); rl; rl=rect_get_system_next(wl))
- {
- win_r.g_x=rl->x;
- win_r.g_y=rl->y;
- win_r.g_w=rl->w;
- win_r.g_h=rl->h;
-
- if (rc_intersect(r, &win_r))
- {
- set_clip(win_r.g_x, win_r.g_y, win_r.g_w, win_r.g_h);
-
- display_window(wl); /* Display the window */
-
- /* send a redraw message to the owner of the window for this rectangle */
- if (!(wl->active_widgets&NO_REDRAWS))
- {
- send_app_message(window_list->owner, WM_ONTOP, 0, window_list->handle, 0, 0, 0, 0);
- send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, win_r.g_x, win_r.g_y, win_r.g_w, win_r.g_h);
- }
- }
-
- }
-
- }
- }
-
- clear_clip();
-
- }
-